﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Windows.Kinect;
using Spine.Unity;
using Joint = Windows.Kinect.Joint;
public class BodySourceView : MonoBehaviour
{
	public Material BoneMaterial;
	public GameObject BodySourceManager;
	public GameObject bodyPrefab;
	public GameObject[] Walls;
	public float zInit;
	public float changeHeadSpeed;
	public float zPara;
	private BodySourceManager _BodyManager;
	private Dictionary<ulong, GameObject> mBodies = new Dictionary<ulong, GameObject>();
	private List<JointType> _joints = new List<JointType> {
		JointType.HandLeft,
		JointType.HandRight,
		JointType.FootLeft,
		JointType.FootRight,
		JointType.SpineBase,
		JointType.Head,
	};
	private void Awake()
	{
		foreach (var wall in Walls)
		{
			wall.SetActive(false);
		}
	}
	void Update()
	{
		if (BodySourceManager == null)
		{
			return;
		}
		_BodyManager = BodySourceManager.GetComponent<BodySourceManager>();
		if (_BodyManager == null)
		{
			return;
		}

		Body[] data = _BodyManager.GetData();
		if (data == null)
		{
			return;
		}
		List<ulong> trackedIds = new List<ulong>();
		foreach (var body in data)
		{
			if (body == null)
			{
				continue;
			}

			if (body.IsTracked)
			{
				trackedIds.Add(body.TrackingId);
			}
		}
		List<ulong> knownIds = new List<ulong>(mBodies.Keys);
		foreach (ulong trackingId in knownIds)
		{
			if (!trackedIds.Contains(trackingId))
			{
				Destroy(mBodies[trackingId]);
				mBodies.Remove(trackingId);
			}
		}

		foreach (var body in data)
		{
			if (body == null)
			{
				continue;
			}
			if (body.IsTracked)
			{
				if (!mBodies.ContainsKey(body.TrackingId))
				{
					mBodies[body.TrackingId] = CreateBodyObject(body.TrackingId);
				}
				RefreshBodyObject(body, mBodies[body.TrackingId]);
			}
		}
	}
	private GameObject CreateBodyObject(ulong id)
	{
		GameObject body = new GameObject("Body:" + id);
		foreach (var wall in Walls)
		{
			wall.SetActive(true);
		}
		GameObject jointObj = Instantiate(bodyPrefab);
		jointObj.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
		jointObj.name = bodyPrefab.ToString();
		jointObj.transform.parent = body.transform;
		return body;
	}
	private void RefreshBodyObject(Body body, GameObject bodyObject)
	{
		foreach (JointType joint in _joints)
		{
			if (joint == JointType.SpineBase)
			{
				Joint sourceJoint = body.Joints[joint];
				Vector3 targetPosition = GetVector3FromJoint(sourceJoint);
				bodyObject.transform.localScale = new Vector3((6 - targetPosition.z) * 0.62f, (6 - targetPosition.z) * 0.62f, 0);
				targetPosition.z = 0;
				Transform jointObject = bodyObject.transform;
				jointObject.position = targetPosition;
			}
			else
			{
				if (joint == JointType.HandLeft)
				{
					if (bodyObject.GetComponentInChildren<UpdateHands>().LeftHand)
					{
						Transform leftH = bodyObject.GetComponentInChildren<UpdateHands>().LeftHand;
						Joint sourceJoint = body.Joints[joint];
						Vector3 targetPosition = GetVector3FromJoint(sourceJoint);
						targetPosition.z = 0;
						leftH.position = targetPosition;
					}
				}
				if (joint == JointType.HandRight)
				{
					if (bodyObject.GetComponentInChildren<UpdateHands>().RightHand)
					{
						Transform rightH = bodyObject.GetComponentInChildren<UpdateHands>().RightHand;
						Joint sourceJoint = body.Joints[joint];
						Vector3 targetPosition = GetVector3FromJoint(sourceJoint);
						targetPosition.z = 0;
						rightH.position = targetPosition;
					}
				}
				if (joint == JointType.FootLeft)
				{
					if (bodyObject.GetComponentInChildren<UpdateFoots>().LeftFoot)
					{
						Transform leftF = bodyObject.GetComponentInChildren<UpdateFoots>().LeftFoot;
						Joint sourceJoint = body.Joints[joint];
						Vector3 targetPosition = GetVector3FromJoint(sourceJoint);
						targetPosition.z = 0;
						leftF.position = targetPosition;
					}
				}
				if (joint == JointType.FootRight)
				{
					if (bodyObject.GetComponentInChildren<UpdateFoots>().RightFoot)
					{
						Transform rightF = bodyObject.GetComponentInChildren<UpdateFoots>().RightFoot;
						Joint sourceJoint = body.Joints[joint];
						Vector3 targetPosition = GetVector3FromJoint(sourceJoint);
						targetPosition.z = 0;
						rightF.position = targetPosition;
					}
				}
				if (joint == JointType.Head)
				{
					if (bodyObject.GetComponentInChildren<UpdateHead>().Head)
					{
						Transform Head = bodyObject.GetComponentInChildren<UpdateHead>().Head;
						Joint sourceJoint = body.Joints[joint];
						Vector3 targetPosition = GetVector3FromJoint(sourceJoint);
						targetPosition.z = 0;
						Head.position = targetPosition;
					}
				}
			}
		}
	}
	private Vector3 GetVector3FromJoint(Joint joint)
	{
		return new Vector3(joint.Position.X * 20, joint.Position.Y * 20, joint.Position.Z);
	}
}
